from alipay import AliPay
from django.shortcuts import render

# Create your views here.
from rest_framework.response import Response

from orders.models import OrderInfo
from pay.models import Payment

"""
创建应用(沙箱应用，测试环境)app_id,网关
设置两队公钥和私钥
    一对是我们应用的
        公钥   需要保存到支付宝网站上
        私钥    我们工程的一个目录中
    一对是支付宝的
        私钥　　在支付宝的服务器上，它自己生成的
        公钥　　我们需要在支付宝的网站上复制下来，放在一个有结束标志的文件中
设置环境(app_id,公钥私钥，sdk)
按照文档开发

"""

"""
当用户点击支付按钮的时候，前端发送一个ajax请求，将订单id发送给我们

必须是登陆用户才能访问
接收并校验参数
根据订单id查询数据
创建支付宝对象
调用支付宝访问生成order_string
拼接url，返回响应

请求方式　GET
请求路径　/orders/(?P<order_id>\d+)/payment/
请求参数　订单id
返回响应　url 支付宝支付链接

"""

from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework import status
# from mall import settings
from django.conf import settings


class PaymentView(APIView):
    # 必须是登陆用户才能访问
    permission_classes = [IsAuthenticated]

    def get(self, request, order_id):
        # 接收并校验参数
        # 根据订单id查询数据
        try:
            order = OrderInfo.objects.get(order_id=order_id,
                                          user=request.user,
                                          status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
        except OrderInfo.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        # 创建支付宝对象
        #  我们的私钥路径
        app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read()
        #  支付宝的公钥路径
        alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read()
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            app_private_key_string=app_private_key_string,
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            alipay_public_key_string=alipay_public_key_string,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG  # 默认False
        )

        # 调用支付宝访问生成order_string
        # 如果你是 Python 3的用户，使用默认的字符串即可
        subject = "测试订单"

        # 电脑网站支付，需要跳转到https://openapi.alipay.com/gateway.do? + order_string
        order_string = alipay.api_alipay_trade_page_pay(
            #  订单id
            out_trade_no=order_id,
            #  支付总金额,需要转换成str类型
            total_amount=str(order.total_amount),
            subject=subject,
            #  回调地址
            return_url="http://www.meiduo.site:8080/pay_success.html",
            notify_url=None  # 可选, 不填则使用默认notify url
        )
        # 拼接url，返回响应
        url = settings.ALIPAY_URL + '?' + order_string
        """
        返回参数
        Cannot GET /pay_success.html?charset=utf-8&
        out_trade_no=20181120084855000000002&
        method=alipay.trade.page.pay.return&
        total_amount=3388.00&
        trade_no=2018112022001448140507972462&
        auth_app_id=2016091900549566&
        version=1.0&
        app_id=2016091900549566&
        sign_type=RSA2&
        seller_id=2088102176369304&
        timestamp=2018-11-20+16%3A53%3A36
        """
        return Response({'alipay_url': url})


"""
我们需要使用支付宝传递回来的一些参数，需要前端传递过来


请求方式　put
请求路径　/pay/status/
"""


class PayStatusAPIView(APIView):
    def put(self, request):
        #  接收参数，转成字典
        data = request.query_params.dict()
        # sign 不能参与签名验证
        signature = data.pop("sign")
        # 创建支付宝对象
        #  我们的私钥路径
        app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read()
        #  支付宝的公钥路径
        alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read()
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,  # 默认回调url
            app_private_key_string=app_private_key_string,
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            alipay_public_key_string=alipay_public_key_string,
            sign_type="RSA2",  # RSA 或者 RSA2
            debug=settings.ALIPAY_DEBUG  # 默认False
        )
        #  进行验证，通过返回True
        success = alipay.verify(data, signature)
        #  判断是否验证通过
        if success:
            #  验证成功之后可以从data中获取支付宝订单id和我们的订单id
            # 支付的订单号
            trade_no = data.get('trade_no')
            #  我们的订单id
            out_trade_no = data.get('out_trade_no')
            #  写入到数据库
            Payment.objects.create(
                order_id=out_trade_no,
                trade_id=trade_no,
            )
            #  更新订单的状态
            OrderInfo.objects.filter(order_id=out_trade_no).update(status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'])
            #  返回响应
            return Response({'trade_id': trade_no})
        else:
            return Response({'message': '非法请求'}, status=status.HTTP_400_BAD_REQUEST)
